package 队列;

import java.util.Scanner;

public class 环形队列 {
	public static void main(String[] args) {
		// 创建一个环形队列
		CircleQueue queue = new CircleQueue(5);
		// 循环菜单
		boolean loop = true;
		// 记录输入
		char key = ' ';
		Scanner scanner = new Scanner(System.in);
		while (loop) {
			System.out.println("s 显示队列");
			System.out.println("a 添加数据");
			System.out.println("g 取出数据");
			System.out.println("h 头部数据");
			System.out.println("n 有效数据");
			System.out.println("e 退出");
			// 获取输入
			key = scanner.next().charAt(0);
			switch (key) {
			case 's':
				queue.showQueue();
				break;
			case 'a':
				System.out.println("输入一个数：");
				int value = scanner.nextInt();
				queue.addQueue(value);
				break;
			case 'g':
				try {
					int res = queue.getQueue();
					System.out.println(res);
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			case 'h':
				try {
					queue.showHead();
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			case 'n':
				queue.showNum();
				break;
			case 'e':
				loop = false;
				break;
			default:
				System.out.println("错误！");
				break;
			}
		}
		System.out.println("程序退出！");
	}
}

class CircleQueue {
	private int maxSize; // 队列最大长度
	private int front; // 队列头
	private int rear; // 队列尾
	private int[] arr; // 队列

	public CircleQueue() {
	}

	// 构造器初始化队列
	public CircleQueue(int maxSize) {
		this.maxSize = maxSize;
		// 初始化队列
		arr = new int[maxSize];
		// 初始化头指针，指向头部，front是指向头的位置
		front = 0;
		// 初始化尾指针，指向尾部后一个位置，空出一个空间做约定，便于查入 判断
		rear = 0;
	}

	// 判断是否空
	public boolean isFull() {
		//头指针和尾指针指向一块空间，头指针追上尾指针
		return front == rear;
	}

	// 判断是否满
	public boolean isEmpty() {
		//如果下一个尾指针指向头，尾指针追上头指针
		return (rear + 1) % maxSize == front;
	}

	// 添加数据
	public void addQueue(int n) {
		if (isEmpty()) {
			System.out.println("队满，无法插入！");
			return;
		}

		// 因为rear指向队尾后一个空间，所以可以直接加
		arr[rear] = n;
		// 加完之后，要使队尾指针向后移一位，保持rear指向空的空间，如果超出maxSize就取模，回到
		// 队头
		rear = (rear + 1) % maxSize;
	}

	// 取出数据
	public int getQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队空，无法取出！");
		}
		//取出头
		int n = arr[front];
		//恢复0
		arr[front] = 0;
		//指向下一个
		front = (front + 1) % maxSize;
		return n;

	}

	// 查看头数据
	public void showHead() {
		if (isFull()) {
			System.out.println("队空，无法查看！");
			return;
		}
		System.out.println(arr[front]);
	}

	// 查看队列
	public void showQueue() {
		if (isEmpty()) {
			System.out.println("队空，无法查看");
			return;
		}
		for(int i = 0 ; i < arr.length ; i++) {
			System.out.println(arr[i]);
		}
	}

	// 查看队列有效数据
	public void showNum() {
		System.out.println((rear + maxSize - front) % maxSize);
	}
}